package com.linghu.ai.service;

import com.linghu.ai.entity.Device;
import com.linghu.ai.repository.DeviceRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 设备管理服务
 * 负责设备的注册、绑定、状态管理等功能
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceService {
    
    private final DeviceRepository deviceRepository;
    
    /**
     * 注册新设备
     * 当ESP32设备首次连接时调用
     */
    @Transactional
    public Device registerDevice(String macAddress, String deviceName, String deviceType, String firmwareVersion) {
        log.info("注册新设备: MAC={}, 名称={}, 类型={}", macAddress, deviceName, deviceType);
        
        // 检查设备是否已存在
        if (deviceRepository.existsByMacAddress(macAddress)) {
            log.warn("设备已存在: MAC={}", macAddress);
            throw new RuntimeException("设备已存在: " + macAddress);
        }
        
        // 创建新设备
        Device device = new Device();
        device.setMacAddress(macAddress);
        device.setDeviceName(deviceName != null ? deviceName : "ESP32设备-" + macAddress.substring(12));
        device.setDeviceType(deviceType != null ? deviceType : "ESP32");
        device.setFirmwareVersion(firmwareVersion);
        device.setStatus(Device.DeviceStatus.ONLINE);
        device.setLastOnlineTime(LocalDateTime.now());
        
        Device savedDevice = deviceRepository.save(device);
        log.info("设备注册成功: ID={}, MAC={}", savedDevice.getId(), macAddress);
        
        return savedDevice;
    }
    
    /**
     * 设备心跳更新
     * ESP32设备定期发送心跳，更新在线状态
     */
    @Transactional
    public void updateDeviceHeartbeat(String macAddress, String ipAddress) {
        log.debug("设备心跳: MAC={}, IP={}", macAddress, ipAddress);
        
        Optional<Device> deviceOpt = deviceRepository.findByMacAddress(macAddress);
        if (deviceOpt.isPresent()) {
            Device device = deviceOpt.get();
            device.setStatus(Device.DeviceStatus.ONLINE);
            device.setIpAddress(ipAddress);
            device.setLastOnlineTime(LocalDateTime.now());
            deviceRepository.save(device);
        } else {
            log.warn("收到未知设备的心跳: MAC={}", macAddress);
        }
    }
    
    /**
     * 获取设备信息
     */
    public Optional<Device> getDeviceByMacAddress(String macAddress) {
        return deviceRepository.findByMacAddress(macAddress);
    }
    
    /**
     * 获取设备信息
     */
    public Optional<Device> getDeviceById(Long id) {
        return deviceRepository.findById(id);
    }
    
    /**
     * 获取所有设备
     */
    public List<Device> getAllDevices() {
        return deviceRepository.findAll();
    }
    
    /**
     * 获取在线设备
     */
    public List<Device> getOnlineDevices() {
        return deviceRepository.findOnlineDevices();
    }
    
    /**
     * 更新设备状态
     */
    @Transactional
    public void updateDeviceStatus(String macAddress, Device.DeviceStatus status) {
        log.info("更新设备状态: MAC={}, 状态={}", macAddress, status);
        deviceRepository.updateDeviceStatusByMacAddress(macAddress, status);
    }
    
    /**
     * 更新设备信息
     */
    @Transactional
    public Device updateDevice(Long id, String deviceName, String deviceType) {
        Optional<Device> deviceOpt = deviceRepository.findById(id);
        if (deviceOpt.isPresent()) {
            Device device = deviceOpt.get();
            if (deviceName != null) {
                device.setDeviceName(deviceName);
            }
            if (deviceType != null) {
                device.setDeviceType(deviceType);
            }
            return deviceRepository.save(device);
        } else {
            throw new RuntimeException("设备不存在: " + id);
        }
    }
    
    /**
     * 删除设备
     */
    @Transactional
    public void deleteDevice(Long id) {
        log.info("删除设备: ID={}", id);
        deviceRepository.deleteById(id);
    }
    
    /**
     * 检查设备是否在线
     * 如果设备超过5分钟没有心跳，认为离线
     */
    @Transactional
    public void checkDeviceOnlineStatus() {
        LocalDateTime offlineThreshold = LocalDateTime.now().minusMinutes(5);
        
        List<Device> onlineDevices = deviceRepository.findByStatus(Device.DeviceStatus.ONLINE);
        for (Device device : onlineDevices) {
            if (device.getLastOnlineTime() != null && 
                device.getLastOnlineTime().isBefore(offlineThreshold)) {
                log.info("设备离线: MAC={}", device.getMacAddress());
                device.setStatus(Device.DeviceStatus.OFFLINE);
                deviceRepository.save(device);
            }
        }
    }
} 